/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package planner_exercise;


import java.util.ArrayList;
import java.util.Random;


/**
 *
 * @author Propietario
 */
public class Planner {
    Stack stack;
    int iter=0;
    int numRail;
    int maxNumRails=3;
    int index;
    Random randomGenerator= new Random();
    String opTypes[] = {"COUPLE","PARK","DETACH","ATTACH","LOAD","UNLOAD"};
    ArrayList<Operators> solution;
    TextProcessor t;
    Items game = new Items();
    String randomWagon;
    public Planner() {//int rails, ArrayList<String> wagons, ArrayList<String> initialPredicates
        //p=new Stack();
        solution=new ArrayList<>();
        t = new TextProcessor("./problem1.txt",game);
        game = t.read();
        stack= new Stack(game.finalState);

        
    }    
    public ArrayList findPlan(){        
        numRail=3;
        /*While stack is full*/
        while(!stack.stackList.isEmpty() &&  !(iter==10000)){
            iter++;
            //Check if elem stack is in state.
            //        1. yes
            //            - erase from stack
            int count2=0;
            
            for(Predicates pr : game.initialState){
                
                if(stack.seeName().equals(pr.name)){
                    
                    System.out.println(""+stack.seeName()+" has been eliminated from stack.");
                    stack.takeOut();         
                    count2++;

                }
            }
            if(count2==0&& !stack.stackList.isEmpty()){     
            //        2. No
            //            a)  Choose Operator: If more than one, choose an 
            //                operator(Random, other strategy)
                if(stack.seeObject() instanceof Predicates ){
                    stack.seeName();
                    Predicates currentPredicate=(Predicates)stack.seeObject();
                    Operators oper;
                    //Check Every operator
                    String obj2="";
                    String obj1="";
                    //DEPENDS ON PRED TYPE:
                    System.out.println("OH!!!!!!!");
                    System.out.println(currentPredicate.type);
                    System.out.println("NOOHHHHH!");
                    switch(currentPredicate.type){
                        case "ON-STATION":
                            obj1=currentPredicate.obj1;
                            obj2=null;
                            System.out.println(currentPredicate.type);
                            break;
                        case "IN-FRONT-OF": 
                            obj1= currentPredicate.obj1;
                            obj2=currentPredicate.obj2;
                            System.out.println(currentPredicate.type);
                            break;
                        case"FREE": 
                            obj2=currentPredicate.obj1;
                            do{
                                index = randomGenerator.nextInt(game.wagons.size());
                                randomWagon = game.wagons.get(index);
                            }while(randomWagon.equals(obj2));
                            obj1 = randomWagon;
                            System.out.println(currentPredicate.type);
                            break;
                        case "FREE-LOCOMOTIVE":
                            index = randomGenerator.nextInt(game.wagons.size());
                            obj1 = game.wagons.get(index);
                            do{
                                index = randomGenerator.nextInt(game.wagons.size());
                                randomWagon = game.wagons.get(index);
                            }while(randomWagon.equals(obj1));   
                            obj2=randomWagon;
                            System.out.println(currentPredicate.type);
                            break;
                        case "TOWED":
                            obj1=currentPredicate.obj1;
                            do{
                                index = randomGenerator.nextInt(game.wagons.size());
                                randomWagon = game.wagons.get(index);
                            }while(randomWagon.equals(obj1));
                            obj2 = randomWagon;
                            System.out.println(currentPredicate.type);
                            break; 
                        case "USED-RAILWAYS":
                            numRail=currentPredicate.railNum;
                            index = randomGenerator.nextInt(game.wagons.size());
                            obj1 = game.wagons.get(index);
                            System.out.println(currentPredicate.type);
                            do{
                                index = randomGenerator.nextInt(game.wagons.size());
                                randomWagon = game.wagons.get(index);
                            }while(randomWagon.equals(obj1));   
                            obj2=randomWagon;
                            System.out.println(currentPredicate.type);
                            break;
                        case "LOADED":
                            obj1=currentPredicate.obj1;
                            obj2=null;
                            System.out.println(currentPredicate.type);
                            break;
                        case "EMPTY":
                            obj1=currentPredicate.obj1;
                            obj2=null;
                            System.out.println(currentPredicate.type);
                            break;
                    }
                    ArrayList<Operators> allOperators=new ArrayList<>();
                    for(String typ : opTypes){
                         
                        oper=new Operators(numRail,typ,obj1,obj2);
                        //Check every element of the add List 
                        
                        
                        //Find all Operators
                        for(Predicates a : oper.add){
                            if(currentPredicate.type.equals(a.type)){
                                allOperators.add(oper);
                                System.out.println("AllOperators "+ iter+ " "+ oper.name);
                            }
                        }                                         
         
                    }
                    
                    //  b)  i) remove element,
                    stack.takeOut();
                    
                    //     ii) add Operator and preconditions to the stack
                    index = randomGenerator.nextInt(allOperators.size());
                    stack.put(allOperators.get(index));
                    System.out.println("Chosen Operator "+ iter+ " "+ allOperators.get(index).name);
                    //    iii) if operator has variable choose one(random, best)
                    for(Predicates b:allOperators.get(index).pre){
                        if(!(b.equals(null))){
                            stack.put(b);
                            System.out.println("Add to Stack "+b.name);
                        }
                    }  
                }else{
                    if(stack.seeObject() instanceof Operators){
                        Operators currentOperator=(Operators)stack.seeObject();
                        solution.add(currentOperator);
            //            c)  If preconditions are in the initial set, remove
            //                from stack with the operator. 
                        // Delete from initial state the delete. 
                        
                        for(Predicates c :currentOperator.del){
                            for(int j=0;j<game.initialState.size();j++){
                                if(c.equals(game.initialState.get(j))) {
                                    System.out.println(""+game.initialState.get(j));
                                    game.initialState.remove(j);
                                    j--;
                                }
                            }
                        }
                        for(Predicates c :currentOperator.add){
                            game.initialState.add(c);
                        }
                        stack.takeOut();
                    }
                }
            }
        }
        System.out.println("Hi "+iter);
        return solution;
    }
    
}